from rest_framework import viewsets, status
from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.contrib.auth.hashers import make_password
from django.db import models
from django.http import HttpResponse
from django.core.exceptions import ValidationError
import csv
import io
import json
from datetime import datetime
from openpyxl import Workbook, load_workbook
from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.utils import get_column_letter
from .models import CustomUser, UserGroup, Role, Menu, MenuPermission, LoginHistory, UserGroupRole, RolePermission, Permission
from .serializers import (
    CustomUserSerializer, CustomUserCreateSerializer, UserGroupSerializer,
    RoleSerializer, MenuSerializer,
    MenuPermissionSerializer, LoginHistorySerializer, UserGroupRoleSerializer
)
from .permissions import RBACPermission, get_user_permissions, get_user_menus, get_user_permissions_detail, get_user_menus_detail


class CustomUserViewSet(viewsets.ModelViewSet):
    """用户管理视图集"""
    queryset = CustomUser.objects.all()
    permission_classes = [IsAuthenticated, RBACPermission]

    def get_serializer_class(self):
        if self.action == 'create':
            return CustomUserCreateSerializer
        return CustomUserSerializer

    def get_queryset(self):
        """过滤查询集"""
        queryset = super().get_queryset()

        # 搜索功能 - 支持用户名、邮箱和姓名
        search = self.request.query_params.get('search')
        if search:
            queryset = queryset.filter(
                models.Q(username__icontains=search) |
                models.Q(email__icontains=search) |
                models.Q(full_name__icontains=search)
            )

        # 状态过滤
        is_active = self.request.query_params.get('is_active')
        if is_active is not None:
            if is_active.lower() == 'true':
                queryset = queryset.filter(is_active=True)
            elif is_active.lower() == 'false':
                queryset = queryset.filter(is_active=False)

        return queryset

    def update(self, request, *args, **kwargs):
        """更新用户"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()

        # 处理密码更新
        if 'password' in request.data:
            request.data['password'] = make_password(request.data['password'])

        # 处理姓名字段同步
        if 'full_name' in request.data:
            # 如果更新 full_name，同时更新 first_name
            request.data['first_name'] = request.data['full_name']
        elif 'first_name' in request.data:
            # 如果更新 first_name，同时更新 full_name
            request.data['full_name'] = request.data['first_name']

        # 处理用户组和角色更新
        user_group_ids = request.data.pop('user_group_ids', None)
        role_ids = request.data.pop('role_ids', None)

        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        # 更新关联关系
        if user_group_ids is not None:
            instance.user_groups.set(user_group_ids)
        if role_ids is not None:
            instance.roles.set(role_ids)

        return Response(serializer.data)

    @action(detail=True, methods=['post'])
    def reset_password(self, request, pk=None):
        """重置用户密码"""
        user = self.get_object()
        new_password = request.data.get('new_password')

        if not new_password:
            return Response({'error': '新密码不能为空'}, status=status.HTTP_400_BAD_REQUEST)

        user.password = make_password(new_password)
        user.save()

        return Response({'message': '密码重置成功'})

    @action(detail=True, methods=['post'])
    def toggle_status(self, request, pk=None):
        """切换用户状态"""
        user = self.get_object()
        user.is_active = not user.is_active
        user.save()

        status_text = '激活' if user.is_active else '禁用'
        return Response({'message': f'用户已{status_text}'})

    @action(detail=True, methods=['get'])
    def permissions(self, request, pk=None):
        """获取用户权限"""
        user = self.get_object()
        permissions = get_user_permissions(user)
        return Response({'permissions': permissions})

    @action(detail=True, methods=['get'])
    def permissions_detail(self, request, pk=None):
        """获取用户权限详细信息（包含来源）"""
        user = self.get_object()
        permissions_detail = get_user_permissions_detail(user)
        return Response(permissions_detail)

    @action(detail=True, methods=['get'])
    def menus_detail(self, request, pk=None):
        """获取用户菜单权限详细信息（包含来源）"""
        user = self.get_object()
        menus_detail = get_user_menus_detail(user)
        return Response(menus_detail)

    @action(detail=True, methods=['get'])
    def menus(self, request, pk=None):
        """获取用户可访问的菜单"""
        user = self.get_object()
        menus = get_user_menus(user)
        serializer = MenuSerializer(menus, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['post'])
    def batch_delete(self, request):
        """批量删除用户"""
        user_ids = request.data.get('user_ids', [])

        if not user_ids:
            return Response({'error': '请选择要删除的用户'}, status=status.HTTP_400_BAD_REQUEST)

        # 检查是否包含当前用户
        if request.user.id in user_ids:
            return Response({'error': '不能删除当前登录用户'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 获取要删除的用户
            users_to_delete = CustomUser.objects.filter(id__in=user_ids)
            deleted_count = users_to_delete.count()

            # 执行删除
            users_to_delete.delete()

            return Response({
                'message': f'成功删除 {deleted_count} 个用户',
                'deleted_count': deleted_count
            })
        except Exception as e:
            return Response({'error': f'删除失败: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['get'])
    def export_template(self, request):
        """下载用户导入模板（Excel格式）"""
        # 创建工作簿
        wb = Workbook()
        ws = wb.active
        ws.title = "用户导入模板"

        # 设置表头
        headers = [
            '用户名*', '邮箱*', '姓名', '电话', '密码*', '是否启用', '是否管理员', '用户组', '角色'
        ]

        # 写入表头并设置样式
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col, value=header)
            cell.font = Font(bold=True, color="FFFFFF")
            cell.fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
            cell.alignment = Alignment(horizontal="center", vertical="center")

        # 写入示例数据
        sample_data = [
            ['zhangsan', 'zhangsan@example.com', '张三', '13800138000', 'password123', '是', '否', '开发组', '普通用户'],
            ['lisi', 'lisi@example.com', '李四', '13800138001', 'password123', '是', '否', '测试组', '普通用户'],
            ['wangwu', 'wangwu@example.com', '王五', '13800138002', 'password123', '是', '否', '运维组', '普通用户']
        ]

        for row_idx, row_data in enumerate(sample_data, 2):
            for col_idx, value in enumerate(row_data, 1):
                ws.cell(row=row_idx, column=col_idx, value=value)

        # 调整列宽
        for col in range(1, len(headers) + 1):
            ws.column_dimensions[get_column_letter(col)].width = 15

        # 添加说明工作表
        ws_info = wb.create_sheet("导入说明")
        info_data = [
            ["用户导入说明", ""],
            ["", ""],
            ["必填字段：", ""],
            ["• 用户名*", "用户登录名，必须唯一"],
            ["• 邮箱*", "用户邮箱地址，必须唯一"],
            ["• 密码*", "用户登录密码，建议8位以上"],
            ["", ""],
            ["可选字段：", ""],
            ["• 姓名", "用户真实姓名"],
            ["• 电话", "联系电话"],
            ["• 是否启用", "填写'是'或'否'，默认为'是'"],
            ["• 是否管理员", "填写'是'或'否'，默认为'否'"],
            ["• 用户组", "用户所属组，如不存在将被忽略"],
            ["• 角色", "用户角色，默认为'普通用户'"],
            ["", ""],
            ["注意事项：", ""],
            ["1. 请勿修改表头行", ""],
            ["2. 用户名和邮箱不能重复", ""],
            ["3. 批量导入的用户默认为普通用户权限", ""],
            ["4. 如果用户组或角色不存在，将使用默认值", ""]
        ]

        for row_idx, (key, value) in enumerate(info_data, 1):
            ws_info.cell(row=row_idx, column=1, value=key)
            ws_info.cell(row=row_idx, column=2, value=value)
            if key and not value:  # 标题行
                cell = ws_info.cell(row=row_idx, column=1)
                cell.font = Font(bold=True, size=14)

        # 调整说明页列宽
        ws_info.column_dimensions['A'].width = 20
        ws_info.column_dimensions['B'].width = 40

        # 创建响应
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename="user_import_template.xlsx"'

        # 保存到响应
        wb.save(response)
        return response

    @action(detail=False, methods=['post'])
    def import_users(self, request):
        """批量导入用户（支持Excel和CSV格式）"""
        if 'file' not in request.FILES:
            return Response({'error': '请上传文件'}, status=status.HTTP_400_BAD_REQUEST)

        file = request.FILES['file']
        file_ext = file.name.lower().split('.')[-1]

        if file_ext not in ['xlsx', 'xls', 'csv']:
            return Response({'error': '请上传Excel(.xlsx/.xls)或CSV格式文件'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            success_count = 0
            error_count = 0
            errors = []

            # 获取默认角色（普通用户）
            default_role = Role.objects.filter(name='普通用户').first()

            # 根据文件类型读取数据
            if file_ext in ['xlsx', 'xls']:
                # 读取Excel文件
                wb = load_workbook(file, data_only=True)
                ws = wb.active

                # 获取表头
                headers = []
                for cell in ws[1]:
                    headers.append(cell.value)

                # 处理数据行
                for row_num, row in enumerate(ws.iter_rows(min_row=2, values_only=True), start=2):
                    if not any(row):  # 跳过空行
                        continue

                    try:
                        # 创建行数据字典
                        row_data = {}
                        for i, value in enumerate(row):
                            if i < len(headers) and headers[i]:
                                row_data[headers[i]] = str(value) if value is not None else ''

                        # 验证必填字段
                        username = row_data.get('用户名*', '').strip()
                        email = row_data.get('邮箱*', '').strip()
                        password = row_data.get('密码*', '').strip()

                        if not username or not email or not password:
                            errors.append(f'第{row_num}行：用户名、邮箱、密码为必填项')
                            error_count += 1
                            continue

                        # 检查用户是否已存在
                        if CustomUser.objects.filter(username=username).exists():
                            errors.append(f'第{row_num}行：用户名 {username} 已存在')
                            error_count += 1
                            continue

                        if CustomUser.objects.filter(email=email).exists():
                            errors.append(f'第{row_num}行：邮箱 {email} 已存在')
                            error_count += 1
                            continue

                        # 创建用户
                        user_data = {
                            'username': username,
                            'email': email,
                            'password': make_password(password),
                            'first_name': row_data.get('姓名', '').strip(),
                            'phone': row_data.get('电话', '').strip(),
                            'is_active': row_data.get('是否启用', '是').strip() == '是',
                            'is_staff': row_data.get('是否管理员', '否').strip() == '是',
                        }

                        user = CustomUser.objects.create(**user_data)

                        # 处理用户组
                        user_group_name = row_data.get('用户组', '').strip()
                        if user_group_name:
                            user_group = UserGroup.objects.filter(name=user_group_name).first()
                            if user_group:
                                user.user_groups.add(user_group)

                        # 处理角色（默认为普通用户）
                        role_name = row_data.get('角色', '普通用户').strip()
                        role = Role.objects.filter(name=role_name).first()
                        if role:
                            user.roles.add(role)
                        elif default_role:
                            user.roles.add(default_role)

                        success_count += 1

                    except Exception as e:
                        errors.append(f'第{row_num}行：{str(e)}')
                        error_count += 1

            else:
                # 读取CSV文件
                file_content = file.read().decode('utf-8-sig')  # 处理BOM
                csv_reader = csv.DictReader(io.StringIO(file_content))

                for row_num, row in enumerate(csv_reader, start=2):
                    try:
                        # 验证必填字段
                        username = row.get('用户名*', '').strip()
                        email = row.get('邮箱*', '').strip()
                        password = row.get('密码*', '').strip()

                        if not username or not email or not password:
                            errors.append(f'第{row_num}行：用户名、邮箱、密码为必填项')
                            error_count += 1
                            continue

                        # 检查用户是否已存在
                        if CustomUser.objects.filter(username=username).exists():
                            errors.append(f'第{row_num}行：用户名 {username} 已存在')
                            error_count += 1
                            continue

                        if CustomUser.objects.filter(email=email).exists():
                            errors.append(f'第{row_num}行：邮箱 {email} 已存在')
                            error_count += 1
                            continue

                        # 创建用户
                        user_data = {
                            'username': username,
                            'email': email,
                            'password': make_password(password),
                            'first_name': row.get('姓名', '').strip(),
                            'phone': row.get('电话', '').strip(),
                            'is_active': row.get('是否启用', '是').strip() == '是',
                            'is_staff': row.get('是否管理员', '否').strip() == '是',
                        }

                        user = CustomUser.objects.create(**user_data)

                        # 处理用户组
                        user_group_name = row.get('用户组', '').strip()
                        if user_group_name:
                            user_group = UserGroup.objects.filter(name=user_group_name).first()
                            if user_group:
                                user.user_groups.add(user_group)

                        # 处理角色（默认为普通用户）
                        role_name = row.get('角色', '普通用户').strip()
                        role = Role.objects.filter(name=role_name).first()
                        if role:
                            user.roles.add(role)
                        elif default_role:
                            user.roles.add(default_role)

                        success_count += 1

                    except Exception as e:
                        errors.append(f'第{row_num}行：{str(e)}')
                        error_count += 1

            return Response({
                'success_count': success_count,
                'error_count': error_count,
                'errors': errors[:10],  # 只返回前10个错误
                'total_errors': len(errors)
            })

        except Exception as e:
            return Response({'error': f'文件处理失败：{str(e)}'}, status=status.HTTP_400_BAD_REQUEST)

    @action(detail=False, methods=['post'])
    def export_users(self, request):
        """导出用户数据（Excel格式）"""
        # 获取查询参数
        queryset = self.filter_queryset(self.get_queryset())

        # 创建工作簿
        wb = Workbook()
        ws = wb.active
        ws.title = "用户数据"

        # 设置表头
        headers = [
            'ID', '用户名', '邮箱', '姓名', '电话', '是否启用', '是否管理员',
            '用户组', '角色', '最后登录时间', '创建时间'
        ]

        # 写入表头并设置样式
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col, value=header)
            cell.font = Font(bold=True, color="FFFFFF")
            cell.fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
            cell.alignment = Alignment(horizontal="center", vertical="center")

        # 写入数据
        for row_idx, user in enumerate(queryset, 2):
            user_groups = ', '.join([group.name for group in user.user_groups.all()])
            roles = ', '.join([role.name for role in user.roles.all()])

            data = [
                user.id,
                user.username,
                user.email,
                user.first_name.strip() or '-',
                user.phone or '-',
                '是' if user.is_active else '否',
                '是' if user.is_staff else '否',
                user_groups or '-',
                roles or '-',
                user.last_login.strftime('%Y-%m-%d %H:%M:%S') if user.last_login else '-',
                user.created_at.strftime('%Y-%m-%d %H:%M:%S')
            ]

            for col_idx, value in enumerate(data, 1):
                cell = ws.cell(row=row_idx, column=col_idx, value=value)
                # 设置数据行样式
                if row_idx % 2 == 0:
                    cell.fill = PatternFill(start_color="F2F2F2", end_color="F2F2F2", fill_type="solid")

        # 调整列宽
        column_widths = [8, 15, 25, 12, 15, 10, 12, 20, 15, 20, 20]
        for col, width in enumerate(column_widths, 1):
            ws.column_dimensions[get_column_letter(col)].width = width

        # 添加统计信息工作表
        ws_stats = wb.create_sheet("统计信息")

        # 统计数据
        total_users = queryset.count()
        active_users = queryset.filter(is_active=True).count()
        inactive_users = queryset.filter(is_active=False).count()
        admin_users = queryset.filter(is_staff=True).count()

        # 角色统计
        role_stats = {}
        for user in queryset:
            for role in user.roles.all():
                role_stats[role.name] = role_stats.get(role.name, 0) + 1

        # 用户组统计
        group_stats = {}
        for user in queryset:
            for group in user.user_groups.all():
                group_stats[group.name] = group_stats.get(group.name, 0) + 1

        # 写入统计信息
        stats_data = [
            ["用户统计信息", ""],
            ["", ""],
            ["总用户数", total_users],
            ["启用用户", active_users],
            ["禁用用户", inactive_users],
            ["管理员用户", admin_users],
            ["", ""],
            ["角色分布", ""],
        ]

        for role_name, count in role_stats.items():
            stats_data.append([f"• {role_name}", count])

        stats_data.extend([
            ["", ""],
            ["用户组分布", ""],
        ])

        for group_name, count in group_stats.items():
            stats_data.append([f"• {group_name}", count])

        stats_data.extend([
            ["", ""],
            ["导出时间", datetime.now().strftime('%Y-%m-%d %H:%M:%S')],
        ])

        for row_idx, (key, value) in enumerate(stats_data, 1):
            ws_stats.cell(row=row_idx, column=1, value=key)
            ws_stats.cell(row=row_idx, column=2, value=value)

            # 设置标题样式
            if key and not value:
                cell = ws_stats.cell(row=row_idx, column=1)
                cell.font = Font(bold=True, size=14)

        # 调整统计页列宽
        ws_stats.column_dimensions['A'].width = 20
        ws_stats.column_dimensions['B'].width = 15

        # 创建响应
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = f'attachment; filename="users_export_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xlsx"'

        # 保存到响应
        wb.save(response)
        return response


class UserGroupViewSet(viewsets.ModelViewSet):
    """用户组管理视图集"""
    queryset = UserGroup.objects.all()
    serializer_class = UserGroupSerializer
    permission_classes = [IsAuthenticated, RBACPermission]

    def get_queryset(self):
        """过滤查询集"""
        queryset = super().get_queryset()

        # 按组名搜索
        name = self.request.query_params.get('name')
        if name:
            queryset = queryset.filter(name__icontains=name)

        return queryset

    @action(detail=True, methods=['get'])
    def users(self, request, pk=None):
        """获取用户组下的用户"""
        group = self.get_object()
        users = group.customuser_set.all()
        serializer = CustomUserSerializer(users, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=['get'])
    def roles(self, request, pk=None):
        """获取用户组分配的角色"""
        group = self.get_object()
        group_roles = UserGroupRole.objects.filter(user_group=group)
        serializer = UserGroupRoleSerializer(group_roles, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=['post'])
    def assign_roles(self, request, pk=None):
        """为用户组分配角色"""
        group = self.get_object()
        role_ids = request.data.get('role_ids', [])

        # 清除现有角色分配
        UserGroupRole.objects.filter(user_group=group).delete()

        # 添加新的角色分配
        for role_id in role_ids:
            try:
                role = Role.objects.get(id=role_id)
                UserGroupRole.objects.create(user_group=group, role=role)
            except Role.DoesNotExist:
                return Response({'error': f'角色ID {role_id} 不存在'}, status=status.HTTP_400_BAD_REQUEST)

        return Response({'message': '角色分配成功'})

    @action(detail=True, methods=['post'])
    def add_users(self, request, pk=None):
        """向用户组添加用户"""
        group = self.get_object()
        user_ids = request.data.get('user_ids', [])

        for user_id in user_ids:
            try:
                user = CustomUser.objects.get(id=user_id)
                user.user_groups.add(group)
            except CustomUser.DoesNotExist:
                return Response({'error': f'用户ID {user_id} 不存在'}, status=status.HTTP_400_BAD_REQUEST)

        return Response({'message': '用户添加成功'})

    @action(detail=True, methods=['post'])
    def remove_users(self, request, pk=None):
        """从用户组移除用户"""
        group = self.get_object()
        user_ids = request.data.get('user_ids', [])

        for user_id in user_ids:
            try:
                user = CustomUser.objects.get(id=user_id)
                user.user_groups.remove(group)
            except CustomUser.DoesNotExist:
                return Response({'error': f'用户ID {user_id} 不存在'}, status=status.HTTP_400_BAD_REQUEST)

        return Response({'message': '用户移除成功'})


class RoleViewSet(viewsets.ModelViewSet):
    """角色管理视图集"""
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    permission_classes = [IsAuthenticated, RBACPermission]

    @action(detail=True, methods=['get'])
    def menus(self, request, pk=None):
        """获取角色的菜单权限"""
        role = self.get_object()
        menu_permissions = MenuPermission.objects.filter(role=role)
        serializer = MenuPermissionSerializer(menu_permissions, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=['post'])
    def assign_menus(self, request, pk=None):
        """分配菜单权限给角色"""
        role = self.get_object()
        menu_ids = request.data.get('menu_ids', [])

        # 清除现有菜单权限
        MenuPermission.objects.filter(role=role).delete()

        # 添加新菜单权限
        for menu_id in menu_ids:
            try:
                menu = Menu.objects.get(id=menu_id)
                MenuPermission.objects.create(role=role, menu=menu)
            except Menu.DoesNotExist:
                return Response({'error': f'菜单ID {menu_id} 不存在'}, status=status.HTTP_400_BAD_REQUEST)

        return Response({'message': '菜单权限分配成功'})

    @action(detail=True, methods=['get'])
    def users(self, request, pk=None):
        """获取角色关联的用户"""
        role = self.get_object()
        users = role.customuser_set.all()
        serializer = CustomUserSerializer(users, many=True)
        return Response({
            'users': serializer.data,
            'count': users.count()
        })

    @action(detail=True, methods=['get'])
    def permissions_detail(self, request, pk=None):
        """获取角色权限详情"""
        role = self.get_object()

        # 获取角色的菜单权限
        menu_permissions = MenuPermission.objects.filter(role=role).select_related('menu')

        # 获取角色的功能权限
        role_permissions = RolePermission.objects.filter(role=role).select_related('permission')

        # 统计信息
        total_menus = Menu.objects.count()
        assigned_menus = menu_permissions.count()
        total_permissions = Permission.objects.count()
        assigned_permissions = role_permissions.count()

        return Response({
            'menu_permissions': MenuPermissionSerializer(menu_permissions, many=True).data,
            'role_permissions': [
                {
                    'permission': {
                        'id': rp.permission.id,
                        'name': rp.permission.name,
                        'code': rp.permission.code,
                        'module': rp.permission.module
                    },
                    'access_level': rp.access_level
                } for rp in role_permissions
            ],
            'summary': {
                'total_menus': total_menus,
                'assigned_menus': assigned_menus,
                'total_permissions': total_permissions,
                'assigned_permissions': assigned_permissions,
                'coverage_percentage': round((assigned_menus / total_menus) * 100, 1) if total_menus > 0 else 0
            }
        })

    @action(detail=True, methods=['get'])
    def deletion_safety_check(self, request, pk=None):
        """检查角色删除的安全性"""
        role = self.get_object()

        # 检查关联用户
        associated_users = role.customuser_set.all()
        users_count = associated_users.count()

        # 检查是否为系统角色（可以通过角色名或特殊标记判断）
        # 注释掉系统角色保护，允许删除所有角色
        # system_roles = ['超级管理员', '系统管理员']
        # is_system_role = role.name in system_roles
        is_system_role = False  # 允许删除所有角色

        # 获取用户详情
        users_info = []
        if users_count > 0:
            users_info = [
                {
                    'id': user.id,
                    'username': user.username,
                    'email': user.email,
                    'is_active': user.is_active
                } for user in associated_users[:10]  # 最多显示10个用户
            ]

        return Response({
            'can_delete': not is_system_role and users_count == 0,
            'has_associated_users': users_count > 0,
            'users_count': users_count,
            'is_system_role': is_system_role,
            'users_info': users_info,
            'warning_message': self._get_deletion_warning(role, users_count, is_system_role)
        })

    def _get_deletion_warning(self, role, users_count, is_system_role):
        """生成删除警告信息"""
        if is_system_role:
            return f'"{role.name}" 是系统预设角色，不能删除'
        elif users_count > 0:
            return f'该角色被 {users_count} 个用户使用，删除后这些用户将失去相关权限'
        else:
            return None

    @action(detail=True, methods=['post'])
    def clone(self, request, pk=None):
        """复制角色"""
        original_role = self.get_object()
        new_name = request.data.get('name')
        new_description = request.data.get('description', f'{original_role.description} (副本)')

        if not new_name:
            return Response({'error': '请提供新角色名称'}, status=status.HTTP_400_BAD_REQUEST)

        # 检查角色名是否已存在
        if Role.objects.filter(name=new_name).exists():
            return Response({'error': '角色名已存在'}, status=status.HTTP_400_BAD_REQUEST)

        # 创建新角色
        new_role = Role.objects.create(
            name=new_name,
            description=new_description
        )

        # 复制菜单权限
        original_menu_permissions = MenuPermission.objects.filter(role=original_role)
        for menu_perm in original_menu_permissions:
            MenuPermission.objects.create(
                role=new_role,
                menu=menu_perm.menu,
                access_level=menu_perm.access_level
            )

        # 复制功能权限
        original_role_permissions = RolePermission.objects.filter(role=original_role)
        for role_perm in original_role_permissions:
            RolePermission.objects.create(
                role=new_role,
                permission=role_perm.permission,
                access_level=role_perm.access_level
            )

        serializer = RoleSerializer(new_role)
        return Response({
            'message': '角色复制成功',
            'role': serializer.data
        }, status=status.HTTP_201_CREATED)

    @action(detail=False, methods=['post'])
    def batch_delete(self, request):
        """批量删除角色"""
        role_ids = request.data.get('role_ids', [])

        if not role_ids:
            return Response({'error': '请选择要删除的角色'}, status=status.HTTP_400_BAD_REQUEST)

        # 安全检查 - 注释掉系统角色保护
        # system_roles = ['超级管理员', '系统管理员']
        # protected_roles = []
        roles_with_users = []

        for role_id in role_ids:
            try:
                role = Role.objects.get(id=role_id)
                # 移除系统角色保护检查
                # if role.name in system_roles:
                #     protected_roles.append(role.name)
                if role.customuser_set.exists():
                    roles_with_users.append({
                        'name': role.name,
                        'users_count': role.customuser_set.count()
                    })
            except Role.DoesNotExist:
                continue

        # 注释掉受保护角色的检查
        # if protected_roles:
        #     return Response({
        #         'error': f'以下系统角色不能删除: {", ".join(protected_roles)}'
        #     }, status=status.HTTP_400_BAD_REQUEST)

        # 如果有关联用户的角色，返回警告信息
        if roles_with_users:
            return Response({
                'warning': True,
                'message': '以下角色有关联用户，删除后用户将失去相关权限',
                'roles_with_users': roles_with_users
            })

        # 执行删除
        deleted_count = Role.objects.filter(id__in=role_ids).delete()[0]

        return Response({
            'message': f'成功删除 {deleted_count} 个角色'
        })

    @action(detail=False, methods=['post'])
    def batch_assign_permissions(self, request):
        """批量分配权限"""
        role_ids = request.data.get('role_ids', [])
        menu_ids = request.data.get('menu_ids', [])

        if not role_ids or not menu_ids:
            return Response({'error': '请选择角色和菜单'}, status=status.HTTP_400_BAD_REQUEST)

        success_count = 0
        for role_id in role_ids:
            try:
                role = Role.objects.get(id=role_id)

                # 清除现有菜单权限
                MenuPermission.objects.filter(role=role).delete()

                # 添加新菜单权限
                for menu_id in menu_ids:
                    try:
                        menu = Menu.objects.get(id=menu_id)
                        MenuPermission.objects.create(role=role, menu=menu)
                    except Menu.DoesNotExist:
                        continue

                success_count += 1
            except Role.DoesNotExist:
                continue

        return Response({
            'message': f'成功为 {success_count} 个角色分配权限'
        })


# PermissionViewSet 已移除，权限管理现在基于菜单权限


class MenuViewSet(viewsets.ModelViewSet):
    """菜单管理视图集"""
    queryset = Menu.objects.filter(parent=None)  # 只返回顶级菜单
    serializer_class = MenuSerializer
    permission_classes = [IsAuthenticated, RBACPermission]

    @action(detail=False, methods=['get'])
    def tree(self, request):
        """获取菜单树"""
        menus = Menu.objects.filter(parent=None, is_active=True).order_by('sort_order')
        serializer = MenuSerializer(menus, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['get'])
    def all_menus(self, request):
        """获取所有菜单（扁平结构）"""
        menus = Menu.objects.all().order_by('level', 'sort_order')
        serializer = MenuSerializer(menus, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['post'])
    def update_order(self, request):
        """更新菜单排序"""
        from django.db import transaction

        menu_orders = request.data.get('menu_orders', [])

        try:
            with transaction.atomic():
                for item in menu_orders:
                    try:
                        menu = Menu.objects.get(id=item['id'])
                        menu.sort_order = item['sort_order']
                        if 'parent_id' in item:
                            menu.parent_id = item['parent_id']
                            menu.level = 1 if item['parent_id'] is None else 2
                        menu.save()
                    except Menu.DoesNotExist:
                        continue

                # 返回更新后的菜单数据
                updated_menus = Menu.objects.filter(level__in=[1, 2]).order_by('level', 'sort_order')
                serializer = MenuSerializer(updated_menus, many=True)

                return Response({
                    'message': '菜单排序更新成功',
                    'menus': serializer.data
                })
        except Exception as e:
            return Response(
                {'error': f'更新菜单排序失败: {str(e)}'},
                status=status.HTTP_400_BAD_REQUEST
            )

    @action(detail=True, methods=['get'])
    def permissions(self, request, pk=None):
        """获取菜单权限"""
        menu = self.get_object()
        menu_permissions = MenuPermission.objects.filter(menu=menu)
        serializer = MenuPermissionSerializer(menu_permissions, many=True)
        return Response(serializer.data)


class MenuPermissionViewSet(viewsets.ModelViewSet):
    """菜单权限管理视图集"""
    queryset = MenuPermission.objects.all()
    serializer_class = MenuPermissionSerializer
    permission_classes = [IsAuthenticated]

    @action(detail=False, methods=['get'])
    def role_menu_matrix(self, request):
        """获取角色菜单权限矩阵"""
        roles = Role.objects.all()
        # 只获取一级和二级菜单，避免重复
        menus = Menu.objects.filter(level__in=[1, 2]).order_by('level', 'sort_order')

        matrix = []
        for role in roles:
            role_menus = MenuPermission.objects.filter(role=role).values_list('menu_id', flat=True)
            role_data = {
                'role_id': role.id,
                'role_name': role.name,
                'menu_permissions': list(role_menus)
            }
            matrix.append(role_data)

        return Response({
            'roles': RoleSerializer(roles, many=True).data,
            'menus': MenuSerializer(menus, many=True).data,
            'matrix': matrix
        })

    @action(detail=False, methods=['post'])
    def batch_assign(self, request):
        """批量分配菜单权限"""
        role_id = request.data.get('role_id')
        menu_ids = request.data.get('menu_ids', [])

        try:
            role = Role.objects.get(id=role_id)

            # 清除现有权限
            MenuPermission.objects.filter(role=role).delete()

            # 添加新权限
            for menu_id in menu_ids:
                try:
                    menu = Menu.objects.get(id=menu_id)
                    MenuPermission.objects.create(role=role, menu=menu)
                except Menu.DoesNotExist:
                    continue

            return Response({'message': f'角色 {role.name} 的菜单权限更新成功'})
        except Role.DoesNotExist:
            return Response({'error': '角色不存在'}, status=status.HTTP_400_BAD_REQUEST)


class LoginHistoryViewSet(viewsets.ReadOnlyModelViewSet):
    """登录历史视图集"""
    queryset = LoginHistory.objects.all()
    serializer_class = LoginHistorySerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = super().get_queryset()
        user_id = self.request.query_params.get('user_id')
        if user_id:
            queryset = queryset.filter(user_id=user_id)
        return queryset


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def current_user_info(request):
    """获取当前用户信息、权限和菜单"""
    user = request.user

    # 用户基本信息
    user_data = CustomUserSerializer(user).data

    # 用户权限
    permissions = get_user_permissions(user)

    # 用户菜单
    menus = get_user_menus(user)
    menu_data = MenuSerializer(menus, many=True).data

    # 构建菜单树
    def build_menu_tree(menu_list):
        menu_dict = {menu['id']: menu for menu in menu_list}
        tree = []

        for menu in menu_list:
            if menu['parent'] is None:
                menu['children'] = []
                tree.append(menu)
            else:
                parent = menu_dict.get(menu['parent'])
                if parent:
                    if 'children' not in parent:
                        parent['children'] = []
                    parent['children'].append(menu)

        return tree

    menu_tree = build_menu_tree(menu_data)

    return Response({
        'user': user_data,
        'permissions': permissions,
        'menus': menu_tree
    })
